// src/services/uploadService.ts
import { v4 as uuidv4 } from 'uuid';

// 文件上传配置
const UPLOAD_CONFIG = {
    API_ENDPOINT: '/api/upload', // 后端上传接口
    MAX_FILE_SIZE: 500 * 1024 * 1024, // 500MB
    SUPPORTED_VIDEO_FORMATS: ['mp4', 'mov', 'avi', 'mkv', 'webm'],
    SUPPORTED_AUDIO_FORMATS: ['mp3', 'wav', 'ogg', 'flac'],
    SUPPORTED_STICKER_FORMATS: ['png', 'jpg', 'jpeg', 'gif', 'svg'],
};

/**
 * 检查文件类型是否支持
 * @param file 文件对象
 * @param type 文件类型（video, audio, sticker）
 * @returns 是否支持
 */
const isFileTypeSupported = (file: File, type: 'video' | 'audio' | 'sticker'): boolean => {
    const fileExtension = file.name.split('.').pop()?.toLowerCase() || '';
    switch (type) {
        case 'video':
            return UPLOAD_CONFIG.SUPPORTED_VIDEO_FORMATS.includes(fileExtension);
        case 'audio':
            return UPLOAD_CONFIG.SUPPORTED_AUDIO_FORMATS.includes(fileExtension);
        case 'sticker':
            return UPLOAD_CONFIG.SUPPORTED_STICKER_FORMATS.includes(fileExtension);
        default:
            return false;
    }
};

/**
 * 检查文件大小是否超过限制
 * @param file 文件对象
 * @returns 是否超过限制
 */
const isFileSizeExceeded = (file: File): boolean => {
    return file.size > UPLOAD_CONFIG.MAX_FILE_SIZE;
};

/**
 * 打开文件选择器
 * @param type 文件类型（video, audio, sticker）
 * @returns Promise<File | null> 选中的文件或null
 */
const openFileSelector = (type: 'video' | 'audio' | 'sticker'): Promise<File | null> => {
    return new Promise((resolve) => {
        const input = document.createElement('input');
        input.type = 'file';
        input.accept = getAcceptString(type);

        input.onchange = (e) => {
            const file = (e.target as HTMLInputElement).files?.[0] || null;
            resolve(file);
        };

        input.click();
    });
};

/**
 * 获取文件选择器的accept字符串
 * @param type 文件类型
 * @returns accept字符串
 */
const getAcceptString = (type: 'video' | 'audio' | 'sticker'): string => {
    switch (type) {
        case 'video':
            return UPLOAD_CONFIG.SUPPORTED_VIDEO_FORMATS.map((ext) => `video/${ext}`).join(',');
        case 'audio':
            return UPLOAD_CONFIG.SUPPORTED_AUDIO_FORMATS.map((ext) => `audio/${ext}`).join(',');
        case 'sticker':
            return UPLOAD_CONFIG.SUPPORTED_STICKER_FORMATS.map((ext) => `image/${ext}`).join(',');
        default:
            return '';
    }
};

/**
 * 上传文件到后端
 * @param file 文件对象
 * @param type 文件类型
 * @param draftId 草稿ID
 * @returns Promise<string> 后端返回的公网URL
 */
const uploadFileToServer = async (file: File, type: 'video' | 'audio' | 'sticker', draftId: string): Promise<string> => {
    try {
        const formData = new FormData();
        formData.append('file', file);
        formData.append('type', type);
        formData.append('draftId', draftId);
        formData.append('timestamp', Date.now().toString());
        formData.append('uuid', uuidv4());

        const response = await fetch(UPLOAD_CONFIG.API_ENDPOINT, {
            method: 'POST',
            body: formData,
        });

        if (!response.ok) {
            throw new Error(`上传失败: ${response.statusText}`);
        }

        const data = await response.json();
        return data.url;
    } catch (error) {
        console.error('文件上传失败:', error);
        throw error;
    }
};

/**
 * 处理文件上传流程
 * @param type 文件类型
 * @param draftId 草稿ID
 * @returns Promise<string | null> 上传后的URL或null
 */
const handleFileUpload = async (type: 'video' | 'audio' | 'sticker', draftId: string): Promise<string | null> => {
    try {
        // 1. 打开文件选择器
        const file = await openFileSelector(type);
        if (!file) return null;

        // 2. 检查文件类型和大小
        if (!isFileTypeSupported(file, type)) {
            alert(`不支持的${getTypeName(type)}文件格式`);
            return null;
        }

        if (isFileSizeExceeded(file)) {
            alert(`${getTypeName(type)}文件大小不能超过${UPLOAD_CONFIG.MAX_FILE_SIZE / (1024 * 1024)}MB`);
            return null;
        }

        // 3. 上传文件
        const url = await uploadFileToServer(file, type, draftId);
        return url;
    } catch (error) {
        alert(`上传${getTypeName(type)}时出错: ${error instanceof Error ? error.message : String(error)}`);
        return null;
    }
};

/**
 * 获取类型名称
 * @param type 类型
 * @returns 类型名称
 */
const getTypeName = (type: 'video' | 'audio' | 'sticker'): string => {
    switch (type) {
        case 'video':
            return '视频';
        case 'audio':
            return '音频';
        case 'sticker':
            return '贴纸';
        default:
            return '';
    }
};

export { handleFileUpload };
